home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / vopts / state.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  16KB  |  535 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. #include "vopts.h"
  7.  
  8. Prototype void handle_hit(struct Gadget *gad,int shift);
  9. Prototype void set_cyc_state(struct G_CYCLE *cyc,struct G_VALUE *val);
  10. Prototype void handle_list(struct G_LIST *list,struct Gadget *gad,int class);
  11. Prototype void redraw_gadget(struct Gadget *gad);
  12. Prototype void recalc_prop(struct G_LIST *list,UWORD *body,UWORD *sltop);
  13. Prototype void set_gadlist(struct GADLIST *gadlist,int state);
  14. Prototype void set_gadgets(int state);
  15.  
  16. /***********************************************************************************
  17.  * Procedure: handle_hit
  18.  * Synopsis:  handle_hit(gadget);
  19.  * Purpose:   Handle the processing for the hit on a gadget.
  20.  ***********************************************************************************/
  21. void handle_hit(struct Gadget *gad,
  22.                 int    shift
  23.                )
  24. {
  25.    struct G_OBJECT *obj;
  26.  
  27.    obj = (struct G_OBJECT *)gad->UserData;
  28.    /* Ignore any hits on disabled gadgets */
  29.    if ((gad->Flags & GADGHIGHBITS) == GADGHNONE) return;
  30.  
  31.    switch(gad->GadgetID)
  32.    {
  33.       case CLASS_CYCLE:
  34.          {
  35.             /* We need to advance the string to the next state */
  36.             /* When we refresh the gadget, we need to first blank it out */
  37.             struct G_CYCLE *cyc;
  38.             struct G_VALUE *val;
  39.  
  40.             cyc = (struct G_CYCLE *)obj;
  41.             val = cyc->curval;
  42.  
  43.             if (shift)
  44.             {
  45.                for(val = cyc->values;
  46.                    (val->next != NULL) && (val->next != cyc->curval);
  47.                    val = val->next);
  48.             }
  49.             else
  50.             {
  51.                val = val->next;
  52.                if (val == NULL) val = cyc->values;
  53.             }
  54.             set_cyc_state(cyc, val);
  55.          }
  56.          break;
  57.       case CLASS_CHECK:
  58.          obj->state = (gad->Flags & SELECTED) != 0;
  59.          break;
  60.       case CLASS_STRING:
  61.          {
  62.          struct StringInfo *si;
  63.          si = (struct StringInfo *)gad->SpecialInfo;
  64.          if ((si->Buffer[0]) || (obj->class != CLASS_LIST)) break;
  65.          }
  66.       case CLASS_DEL:
  67.       case CLASS_LIST:
  68.       case CLASS_LIST1:
  69.       case CLASS_LIST2:
  70.       case CLASS_ADD:
  71.       case CLASS_UP:
  72.       case CLASS_DOWN:
  73.       case CLASS_PROP:
  74.          handle_list((struct G_LIST *)obj, gad, gad->GadgetID);
  75.          break;
  76.       case CLASS_GROUP:
  77.          /* We need to advance to the next valid group */
  78.          {
  79.          int scope;
  80.          switch (global.filetype)
  81.          {
  82.             case FILE_OPTIONS:
  83.             case FILE_C:
  84.             case FILE_DMAKEFILE:
  85.                scope = 2;   /* note that global.filetype cannot == 2 */
  86.                break;
  87.             default:
  88.                /* FILE_ENV, uninitialized or whatever */
  89.                scope = 1;   /* to skip over non global options       */
  90.          }
  91.          do
  92.          {
  93.             if (shift)
  94.             {
  95.                global.curgroup = (struct G_GROUP *)global.curgroup->base.prev;
  96.                if (global.curgroup == NULL)
  97.                {
  98.                   global.curgroup = global.groups;
  99.                   while(global.curgroup->base.next != NULL)
  100.                      global.curgroup = (struct G_GROUP *)global.curgroup->base.next;
  101.                }
  102.             }
  103.             else
  104.             {
  105.                global.curgroup = (struct G_GROUP *)global.curgroup->base.next;
  106.                if (global.curgroup == NULL) global.curgroup = global.groups;
  107.             }
  108.          /* accept anything for options, c or dmakefile,  */
  109.          /* but only local for env                        */
  110.          } while (global.curgroup->local == scope);
  111.          set_group_gadgets();
  112.          break;
  113.          }
  114.       case CLASS_BUTTON:
  115.          switch(obj->state)
  116.          {
  117.             case BUTTON_SAVE:
  118.                /* Save the defaults permanently */
  119.                do_command("SAVE");
  120.                global.done = 1;
  121.                break;
  122.             case BUTTON_USE:
  123.                /* Use as the current defaults */
  124.                do_command("SAVE ENV");
  125.                global.done = 1;
  126.                break;
  127.             case BUTTON_CANCEL:
  128.                /* Just quit and don't do anything */
  129.                global.done = 1;
  130.                break;
  131.             case BUTTON_FRSAVE:
  132.             {
  133.                static char command[MAX_STRING+5];
  134.  
  135.                /* remove default file requester   */
  136.                clear_fr_gadgets();
  137.                /*copy string to global.filename and continue file operation */
  138.                strcpy(global.filename, global.frstring.buf);
  139.  
  140. #ifdef JGM_DBG
  141. printf("global.fileop = %ld\n", global.fileop);
  142. #endif
  143.                if (global.fileop == 0)   /* READ in progress */
  144.                   strcpy(command, "READ ");
  145.                else
  146.                {
  147.                   if (global.fileop == 1)
  148.                      strcpy(command, "SAVE ");
  149.                   else
  150.                      return;
  151.                }
  152. #ifdef JGM_DBG
  153. printf(">>%s<<\n", command);
  154. #endif
  155.                strcat(command, global.frstring.buf);
  156. #ifdef JGM_DBG
  157. printf(">>%s<<\n", command);
  158. #endif
  159.                global.nameoffile = 0; /* name may now be unsafe to write */
  160.                do_command(command);
  161.                break;
  162.             }
  163.             case BUTTON_FRCNCL:
  164.                /* clear file requester and do nothing */
  165.                clear_fr_gadgets();
  166.                break;
  167.          }
  168.          break;
  169.       default:
  170.          break;
  171.    }
  172. }
  173. /***********************************************************************************
  174.  * Procedure: redraw_gadget
  175.  * Synopsis:  redraw_gadget(gadget);
  176.  * Purpose:   Rerender a gadget on the screen
  177.  ***********************************************************************************/
  178. void redraw_gadget(struct Gadget *gad
  179.                   )
  180. {
  181.    SetBPen(global.rp, 0);
  182.    SetAPen(global.rp, 0);
  183.    RectFill( global.rp, gad->LeftEdge + VBAR, gad->TopEdge + HBAR,
  184.                          gad->LeftEdge + gad->Width - 1 - VBAR,
  185.                          gad->TopEdge + gad->Height - 1 - HBAR);
  186.    RefreshGList( gad, global.window, NULL, 1);
  187. }
  188.  
  189. /***********************************************************************************
  190.  * Procedure: set_cyc_state
  191.  * Synopsis:  set_cyc_state(cyc,val)
  192.  * Purpose:   Set a cycle gadget to a give value
  193.  ***********************************************************************************/
  194. void set_cyc_state(struct G_CYCLE *cyc,
  195.                    struct G_VALUE *val
  196.                   )
  197. {
  198.    struct G_STRING *str;
  199.    struct Gadget *gad;
  200.  
  201.    /* See It is currently being displayed on the screen.  If so, we will have to */
  202.    /* do some cleanup work to get it updated.                                    */
  203.    str = cyc->curval->string;
  204.    if ((str != NULL) && (str->base.gadget != NULL))
  205.    {
  206.       /* If there is a string gadget currently in the cycle gadget, we need */
  207.       /* to free it up                                                      */
  208.       RemoveGList( global.window, str->base.gadget, 1);
  209.       free_gadget(str->base.gadget);
  210.    }
  211.  
  212.    if (val == NULL) return;
  213.  
  214.    cyc->curval = val;
  215.  
  216.    /* Now, if we are currently displaying the gadget, we need to get it on the */
  217.    /* screen.                                                                  */
  218.    if (gad = cyc->base.gadget)
  219.    {
  220.       struct IntuiText *itext;
  221.       struct Gadget *strgad;
  222.       int oldpos;
  223.  
  224.       itext = gad->GadgetText->NextText;
  225.       itext->IText = val->title;
  226.  
  227.       strgad = setup_cycle_gadget(gad, itext, val);
  228.  
  229.       oldpos = RemoveGList(global.window, gad, 1);
  230.       AddGList(global.window, gad, oldpos, 1, NULL);
  231.  
  232.       if (strgad) AddGadget( global.window, strgad, 0);
  233.  
  234.       /* Wipe out the inner area of the gadget so that we can redraw it later */
  235.       redraw_gadget(gad);
  236.       if (strgad) redraw_gadget(strgad);
  237.    }
  238. }
  239.  
  240. /***********************************************************************************
  241.  * Procedure: handle_list
  242.  * Synopsis:  handle_list(list, gadget, int class);
  243.  * Purpose:   Handle the processing for the hit on a list gadget.
  244.  ***********************************************************************************/
  245. void handle_list(struct G_LIST *list,
  246.                  struct Gadget *gad,
  247.                  int class
  248.                 )
  249. {
  250.    struct G_ENTRY *ent, *prevent;
  251.    struct PropInfo *pi;
  252.    int expect;
  253.    int pos;
  254.    int i;
  255.    int oldpos[MAX_LIST];
  256.  
  257.    expect = 0;
  258.    if (list->string)
  259.    {
  260.       expect = 1;
  261.    }
  262.  
  263.    pos = list->base.state;
  264.  
  265.    switch(class)
  266.    {
  267.       case CLASS_LIST:
  268.       case CLASS_LIST1:
  269.       case CLASS_LIST2:
  270.          pos = class - CLASS_LIST;
  271.          expect = 1;
  272.          break;
  273.       case CLASS_ADD:
  274.          ent = get_mem(sizeof(struct G_ENTRY));
  275.          if (ent == NULL) return;
  276.          if (list->first == NULL)
  277.          {
  278.             int oldpos;
  279.             oldpos = RemoveGList(global.window, list->delgad, 1);
  280.             list->delgad->Flags   &= ~GADGDISABLED;
  281.             AddGList(global.window, list->delgad, oldpos, 1, NULL);
  282.             redraw_gadget(list->delgad);
  283.          }
  284.          prevent = list->top;
  285.          for (i = 0; (i < pos) && (prevent != NULL); i++)
  286.             prevent = (struct G_ENTRY *)prevent->base.next;
  287.          /* Insert in front of prevent */
  288.          ent->base.next = (struct G_OBJECT *)prevent;
  289.          if (prevent)
  290.          {
  291.             ent->base.prev = prevent->base.prev;
  292.             prevent->base.prev = (struct G_OBJECT *)ent;
  293.          }
  294.          if (ent->base.prev)
  295.          {
  296.             if (list->top == prevent) list->top = ent;
  297.             ent->base.prev->next = (struct G_OBJECT *)ent;
  298.          }
  299.          else
  300.          {
  301.             list->top = list->first = ent;
  302.          }
  303.          expect = 1;
  304.          break;
  305.       case CLASS_STRING:
  306.          {
  307.          struct StringInfo *si;
  308.          si = (struct StringInfo *)gad->SpecialInfo;
  309.          if (si->Buffer[0]) break;
  310.          }
  311.       case CLASS_DEL:
  312.          ent = list->top;
  313.          for (i = 0; (i < pos) && (ent != NULL); i++)
  314.             ent = (struct G_ENTRY *)ent->base.next;
  315.          /* We want to delete ent */
  316.          if (ent == NULL) return;
  317.          if (ent->base.next)
  318.             ent->base.next->prev = ent->base.prev;
  319.          if (ent->base.prev)
  320.             ent->base.prev->next = ent->base.next;
  321.          else
  322.             list->first = (struct G_ENTRY *)ent->base.next;
  323.  
  324.          /* Update the base pointer so that we are looking at the right space */
  325.          if (list->top == ent)
  326.          {
  327.             list->top = (struct G_ENTRY *)ent->base.next;
  328.             if (list->top == NULL)
  329.                list->top = (struct G_ENTRY *)ent->base.prev;
  330.          }
  331.          free_mem(ent, sizeof(struct G_ENTRY));
  332.       case CLASS_REFRESH:
  333.          {
  334.             int oldpos;
  335.  
  336.             expect = 0;
  337.             oldpos = RemoveGList(global.window, list->delgad, 1);
  338.             if (list->first == NULL)
  339.                list->delgad->Flags   |=  GADGDISABLED;
  340.             else
  341.                list->delgad->Flags   &= ~GADGDISABLED;
  342.             AddGList(global.window, list->delgad, oldpos, 1, NULL);
  343.             redraw_gadget(list->delgad);
  344.          }
  345.          RefreshGList( list->delgad, global.window, NULL, 5);
  346.          break;
  347.       case CLASS_UP:
  348.          if ((list->top != NULL) && (list->top->base.prev != NULL))
  349.          {
  350.             list->top = (struct G_ENTRY *)list->top->base.prev;
  351.          }
  352.          break;
  353.       case CLASS_DOWN:
  354.          if ((list->top != NULL) && (list->top->base.next != NULL))
  355.          {
  356.             list->top = (struct G_ENTRY *)list->top->base.next;
  357.          }
  358.          break;
  359.       case CLASS_PROP:
  360.          pi = (struct PropInfo *)gad->SpecialInfo;
  361.          list->top = list->first;
  362.          i = (pi->VertPot*list->maxent)/MAXBODY;
  363.          if (i >= list->maxent) i = list->maxent - 1;
  364.          while((i > 0) && (list->top != NULL))
  365.          {
  366.             list->top = (struct G_ENTRY *)list->top->base.next;
  367.             i--;
  368.          }
  369.          if (list->top == NULL) list->top = list->first;
  370.          break;
  371.    }
  372.  
  373.    list->base.state = pos;
  374.  
  375.    gad = list->base.gadget;
  376.    list->string = 0;
  377.  
  378.    if (expect)
  379.    {
  380.       /* Make sure that we are actually in a position to enable the */
  381.       /* requested string gadget.  If not, just ignore the request  */
  382.       ent = list->top;
  383.       for(i = pos; ent && (i > 0); i--)
  384.          ent = (struct G_ENTRY *)ent->base.next;
  385.  
  386.       if (ent)
  387.          list->string = 1;
  388.       else
  389.       {
  390.          pos = -1;
  391.          list->base.state = 0;
  392.       }
  393.    }
  394.    else
  395.    {
  396.       pos = -1;
  397.    }
  398.  
  399.    for(i = MAX_LIST-1; i >= 0; i--)
  400.    {
  401.       oldpos[i] = RemoveGList(global.window, list->btngad[i], 2);
  402.    }
  403.    reset_list_object(list, pos);
  404.  
  405.    /* Wipe out the inner area of the gadget so that we can redraw it later */
  406.    redraw_gadget(gad);
  407.  
  408.    for(i = 0; i < MAX_LIST; i++)
  409.    {
  410.       AddGList(global.window, list->btngad[i], oldpos[i], 2, NULL);
  411.       RefreshGList( list->btngad[i], global.window, NULL, 2);
  412.    }
  413.    if (pos >= 0)
  414.       ActivateGadget(list->strgad[pos], global.window, NULL);
  415.  
  416.    {
  417.       UWORD body, sltop;
  418.       recalc_prop(list, &body, &sltop);
  419.  
  420. #ifdef NewModifyProp
  421. #undef NewModifyProp
  422. #endif
  423.       NewModifyProp(list->slider, global.window, NULL,
  424.                     AUTOKNOB | FREEVERT | PROPBORDERLESS,
  425.                     0, sltop, MAXBODY, body, 1L);
  426.    }
  427. }
  428. /***********************************************************************************
  429.  * Procedure: recalc_prop
  430.  * Synopsis:  recalc_prop(list)
  431.  * Purpose:   Calculate the appropriate BODY and TOP values for a List Prop gadget
  432.  ***********************************************************************************/
  433. void recalc_prop(struct G_LIST *list,
  434.                  UWORD *body, UWORD *sltop
  435.                )
  436. {
  437.    int count, top;
  438.    struct G_ENTRY *ent;
  439.  
  440.    count = top = 0;
  441.    ent = list->first;
  442.  
  443.    while(ent != NULL)
  444.    {
  445.       if (ent == list->top) top = count;
  446.       count++;
  447.       ent = (struct G_ENTRY *)ent->base.next;
  448.    }
  449.  
  450.    list->maxent = count;
  451.  
  452.    *body  = MAXBODY;
  453.    *sltop = 0;
  454.    if (count > MAX_LIST)
  455.       *body  = (MAXBODY * MAX_LIST) / count;
  456.  
  457.    if (count)
  458.       *sltop = (MAXBODY * top     ) / count;
  459. }
  460. /***********************************************************************************
  461.  * Procedure: set_gadlist
  462.  * Synopsis:  set_gadlist(gadlist,on/off)
  463.  * Purpose:   Enable or Disable all the gadgets in a list
  464.  ***********************************************************************************/
  465. void set_gadlist(struct GADLIST *gadlist,
  466.                  int state
  467.                 )
  468. {
  469.    struct Gadget *gad;
  470.    struct G_CYCLE *cyc;
  471.    int count;
  472.  
  473.    if ((global.window == NULL) ||
  474.        (gadlist == NULL))
  475.       return;
  476.  
  477.    if (state)
  478.    {
  479. #ifdef AddGList
  480. #undef AddGList
  481. #endif
  482.       AddGList( global.window, gadlist->gadgets, 30000, gadlist->count, NULL);
  483.    }
  484.    else
  485.    {
  486.       RemoveGList(global.window, gadlist->gadgets, gadlist->count);
  487.    }
  488.  
  489.    for(gad = gadlist->gadgets, count=gadlist->count;
  490.        gad && count;
  491.        gad = gad->NextGadget, count--)
  492.    {
  493.       cyc = (struct G_CYCLE *)gad->UserData;
  494.  
  495.       if (cyc->base.class == CLASS_CYCLE)
  496.       {
  497.          set_cyc_state(cyc, state ? cyc->curval : NULL);
  498.       }
  499.       else if (state)
  500.       {
  501.          if (cyc->base.class == CLASS_LIST)
  502.          {
  503.             if (gad == cyc->base.gadget)
  504.                handle_list((struct G_LIST *)cyc, NULL, CLASS_REFRESH);
  505.          }
  506.          else
  507.          {
  508.         if (cyc->base.class == CLASS_CHECK)
  509.         {
  510.            if (cyc->base.state)
  511.            {
  512.           gad->Flags |= SELECTED;
  513.            }
  514.            else
  515.            {
  516.           gad->Flags &= ~SELECTED;
  517.            }
  518.         }
  519.              RefreshGList(gad, global.window, NULL, 1);
  520.          }
  521.       }
  522.    }
  523. }
  524.  
  525. /***********************************************************************************
  526.  * Procedure: set_gadgets
  527.  * Synopsis:  set_gadgets(on/off)
  528.  * Purpose:   Enable or Disable all gadgets
  529.  ***********************************************************************************/
  530. void set_gadgets(int state)
  531. {
  532.    set_gadlist(global.gadlist,    state);
  533.    set_gadlist(global.grpgadlist, state);
  534. }
  535.